from datetime import datetime

from flask import Blueprint, request, current_app, g
from util.permission import permission_required
from util.result import Result
from models import db, Category, Book

# 创建分类管理的蓝图
api_bp = Blueprint('category', __name__)


# 1. 创建分类接口（需要category:create权限）
@api_bp.route('/category', methods=['POST'])
@permission_required('category:create')
def create_category():
    try:
        data = request.get_json()
        if not data:
            return Result.error("请输入分类信息")

        # 验证必填字段
        required_fields = ['name', 'code']
        for field in required_fields:
            if field not in data or not str(data[field]).strip():
                return Result.error(f"{field} 是必填项")

        # 处理输入数据（去除首尾空格）
        name = str(data['name']).strip()
        code = str(data['code']).strip()

        # 检查分类编码和名称是否已存在
        if Category.query.filter_by(code=code).first():
            return Result.error("分类编码已存在")
        if Category.query.filter_by(name=name).first():
            return Result.error("分类名称已存在")

        # 创建新分类
        new_category = Category(
            name=name,
            code=code,
            created_at=datetime.now(),
            updated_at=datetime.now()
        )

        db.session.add(new_category)
        db.session.commit()

        return Result.success("分类创建成功")

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建分类异常: {str(e)}")
        return Result.error("创建分类失败，请稍后重试")


# 2. 分页查询分类接口（需要category:read权限，支持筛选、排序）
@api_bp.route('/category', methods=['GET'])
@permission_required('category:read')
def search_category():
    try:
        # 1. 获取分页参数（默认第1页，每页10条）
        page = request.args.get('page', type=int)  # 当前页码
        size = request.args.get('size', type=int)  # 每页条数
        # 页码和条数合法性校验
        if page < 1:
            page = 1
        if size < 1 or size > 100:  # 限制最大每页100条，避免性能问题
            size = 10

        # 2. 获取筛选参数
        kw = request.args.get('kw').strip()  # 名称模糊筛选
        begin = request.args.get('begin',type=str)
        end = request.args.get('end',type=str)
        # 3. 构建查询条件
        query = Category.query
        if kw:
            query = query.filter((Category.name.like(f"%{kw}%") | Category.code.like(f"%{kw}%")))

        # 时间范围筛选（begin 和 end 为时间戳）
        if begin:
            begin=datetime.strptime(begin, '%Y-%m-%d')
            query = query.filter(Category.created_at >= begin)

        if end:
            end=datetime.strptime(end, '%Y-%m-%d')
            query = query.filter(Category.created_at <= end)

        # 4. 构建排序条件（默认按创建时间倒序）
        query = query.order_by(Category.created_at.desc())

        # 5. 执行分页查询（SQLAlchemy内置分页方法）
        paginated_result = query.paginate(page=page, per_page=size, error_out=False)
        # 获取当前页数据
        categories = paginated_result.items

        # 6. 格式化返回数据
        result_list = [{
            "id": cat.id,
            "name": cat.name,
            "code": cat.code,
            "created_at": cat.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "updated_at": cat.updated_at.strftime("%Y-%m-%d %H:%M:%S")
        } for cat in categories]

        # 7. 构建分页响应体（包含分页元信息，方便前端渲染分页组件）
        page_data = {
            "total": paginated_result.total,  # 总记录数
            "page": page,  # 当前页码
            "size": size,  # 每页条数
            "list": result_list  # 当前页数据列表
        }

        return Result.success("分页查询成功", data=page_data)

    except Exception as e:
        current_app.logger.error(f"分类分页查询异常: {str(e)}")
        return Result.error("分页查询分类失败，请稍后重试")

# 3. 更新分类接口（需要category:edit权限）
@api_bp.route('/category', methods=['PUT'])
@permission_required('category:update')
def update_category():
    try:
        data = request.get_json()
        if not data:
            return Result.error("请输入更新信息")

        # 必须提供id才能更新
        category_id = data.get('id')
        if not category_id:
            return Result.error("请提供分类ID")

        # 查询指定ID的分类
        category = Category.query.get(category_id)
        if not category:
            return Result.error("未找到指定分类")

        # 检查分类名称是否重复（排除当前分类）
        if 'name' in data and data['name'] is not None:
            new_name = str(data['name']).strip()
            # 排除当前分类ID，检查是否有同名分类
            existing = Category.query.filter(
                Category.name == new_name,
                Category.id != category_id
            ).first()
            if existing:
                return Result.error("分类名称已存在")
            category.name = new_name

        # 处理分类编码（去除首尾空格）
        if 'code' in data and data['code'] is not None:
            new_code = str(data['code']).strip()
            # 排除当前分类ID，检查是否有同编码分类
            existing = Category.query.filter(
                Category.code == new_code,
                Category.id != category_id
            ).first()
            if existing:
                return Result.error("分类编码已存在")
            category.code = new_code

        # 修改分类的更新时间
        category.updated_at = datetime.now()

        db.session.commit()
        return Result.success("分类更新成功")

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新分类异常: {str(e)}")
        return Result.error("更新分类失败，请稍后重试")

# 4. 删除分类接口（需要category:delete权限）
@api_bp.route('/category/<int:category_id>', methods=['DELETE'])
@permission_required('category:delete')
def delete_category(category_id):
    try:
        category = Category.query.get(category_id)
        if not category:
            return Result.error("分类不存在")

        db.session.delete(category)
        db.session.commit()

        return Result.success("分类删除成功")

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除分类异常: {str(e)}")
        return Result.error("删除分类失败，请稍后重试")

# 5. 获取全部分类接口（需要category:read权限）
@api_bp.route('/category/all', methods=['GET'])
@permission_required('category:read')
def all_category():
    try:
        data = [{
            "value": category.name,
            "label": category.name,
        } for category in Category.query.all()]
        return Result.success(data=data)

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"获取全部分类数据异常: {str(e)}")
        return Result.error("获取全部分类数据失败，请稍后重试")
